import {
  User,
  Book,
  Voucher,
  BookMap,
  Tradable,
  TonOrder,
  ENUM_VOUCHER,
  ENUM_TON_ORDER,
  ENUM_BOOK_TYPE,
  WithKeySortBook,
  WithBookSummary,
  ENUM_BOOK_DIRECTION,
} from "qqlx-core";
import { toNumber } from "@lib/com.verify";
import { getTonOrderTrans } from "@/river/data-river-ton-trans";

import { BookSchema } from "@/pond/schema-book";

/** 期末余额是否在借方 */
export function isAmountFromJie(type: ENUM_BOOK_TYPE) {
  return [
    ENUM_BOOK_TYPE.CUN_KUAN_ZHANG_HU,
    ENUM_BOOK_TYPE.YING_SHOU_ZHANG_KUAN_ORDER,
    ENUM_BOOK_TYPE.YING_SHOU_ZHANG_KUAN_RETURN_ORDER,
    ENUM_BOOK_TYPE.YING_FU_ZHANG_KUAN_CHECKING,
    ENUM_BOOK_TYPE.ZHU_YING_YE_WU_SHOU_RU_CHECKING,
    ENUM_BOOK_TYPE.ZHU_YING_YE_WU_SHOU_RU_RETURN_CHECKING,
    ENUM_BOOK_TYPE.ZHU_YING_YE_WU_CHENG_BEN_ORDER,
    ENUM_BOOK_TYPE.ZHU_YING_YE_WU_CHENG_BEN_TAX,
  ].includes(type);
}

// ============================ 订单的明细账簿 ============================
// ============================ 订单的明细账簿 ============================
// ============================ 订单的明细账簿 ============================
// ============================ 订单的明细账簿 ============================
// ============================ 订单的明细账簿 ============================
// ============================ 订单的明细账簿 ============================

/** 创建订单后，首次对订单进行记账 */
export function getTonOrderBookType(existType: ENUM_TON_ORDER) {
  if (existType === ENUM_TON_ORDER.SALE) {
    return {
      typeJIE: ENUM_BOOK_TYPE.YING_SHOU_ZHANG_KUAN_ORDER,
      typeDAI: ENUM_BOOK_TYPE.ZHU_YING_YE_WU_SHOU_RU_ORDER,
    };
  } else if (existType === ENUM_TON_ORDER.SALE_RETURN) {
    return {
      typeJIE: ENUM_BOOK_TYPE.ZHU_YING_YE_WU_SHOU_RU_RETURN_ORDER,
      typeDAI: ENUM_BOOK_TYPE.YING_SHOU_ZHANG_KUAN_RETURN_ORDER,
    };
  } else if (existType === ENUM_TON_ORDER.PURCHASE) {
    return {
      typeJIE: ENUM_BOOK_TYPE.ZHU_YING_YE_WU_CHENG_BEN_ORDER,
      typeDAI: ENUM_BOOK_TYPE.YING_FU_ZHANG_KUAN_ORDER,
    };
  } else {
    throw { message: `暂不支持${getTonOrderTrans(existType)?.zh}` };
  }
}

/** 订单（采购/销售）在列表上要看到哪些明细账簿？*/
export function getTonOrderBookQuery(tonType: ENUM_TON_ORDER, sortorKey: WithKeySortBook) {
  const { typeJIE, typeDAI } = getTonOrderBookType(tonType);

  const sortorQuery = {
    type: ENUM_BOOK_TYPE.NONE,
    direction: ENUM_BOOK_DIRECTION.NONE,
  };

  if (tonType === ENUM_TON_ORDER.SALE) {
    if (sortorKey === "amountA1") {
      sortorQuery.type = typeJIE; // 应收帐款
      sortorQuery.direction = ENUM_BOOK_DIRECTION.NONE;
    } else if (sortorKey === "amountA2") {
      sortorQuery.type = typeJIE;
      sortorQuery.direction = ENUM_BOOK_DIRECTION.DAI;
    } else if (sortorKey === "amountA3") {
      sortorQuery.type = typeDAI; // 主营业务收入
      sortorQuery.direction = ENUM_BOOK_DIRECTION.NONE;
    } else if (sortorKey === "amountA4") {
      sortorQuery.type = typeDAI;
      sortorQuery.direction = ENUM_BOOK_DIRECTION.JIE;
    }
  } else if (tonType === ENUM_TON_ORDER.SALE_RETURN) {
    if (sortorKey === "amountA1") {
      sortorQuery.type = typeDAI; // 应收帐款
      sortorQuery.direction = ENUM_BOOK_DIRECTION.NONE;
    } else if (sortorKey === "amountA2") {
      sortorQuery.type = typeDAI;
      sortorQuery.direction = ENUM_BOOK_DIRECTION.JIE;
    } else if (sortorKey === "amountA3") {
      sortorQuery.type = typeDAI; // 不考虑发票
      sortorQuery.direction = ENUM_BOOK_DIRECTION.NONE;
    } else if (sortorKey === "amountA4") {
      sortorQuery.type = typeDAI; // 不考虑发票
      sortorQuery.direction = ENUM_BOOK_DIRECTION.NONE;
    }
  } else if (tonType === ENUM_TON_ORDER.PURCHASE) {
    if (sortorKey === "amountA1") {
      sortorQuery.type = typeDAI; // 应付账款
      sortorQuery.direction = ENUM_BOOK_DIRECTION.NONE;
    } else if (sortorKey === "amountA2") {
      sortorQuery.type = typeDAI;
      sortorQuery.direction = ENUM_BOOK_DIRECTION.JIE;
    } else if (sortorKey === "amountA3") {
      sortorQuery.type = typeJIE; // 主营业务成本
      sortorQuery.direction = ENUM_BOOK_DIRECTION.NONE;
    } else if (sortorKey === "amountA4") {
      sortorQuery.type = typeJIE;
      sortorQuery.direction = ENUM_BOOK_DIRECTION.DAI;
    }
  }
  return sortorQuery;
}

/** 帮助订单，补充明细账信息 */
export function formatTonOrderBook(type: ENUM_TON_ORDER, orders: TonOrder[]) {
  return orders.map((o) => {
    const _o = o as WithBookSummary & TonOrder;

    const _joins = o.joinBookMapList || [];
    const query1 = getTonOrderBookQuery(type, "amountA1");
    const query1calc = sumBookMap(query1.type, _joins);
    if (query1.direction === ENUM_BOOK_DIRECTION.NONE) {
      _o.amountA1 = query1calc.amount;
    } else if (query1.direction === ENUM_BOOK_DIRECTION.JIE) {
      _o.amountA1 = query1calc.amountJie;
    } else if (query1.direction === ENUM_BOOK_DIRECTION.DAI) {
      _o.amountA1 = query1calc.amountDai;
    }

    const query2 = getTonOrderBookQuery(type, "amountA2");
    const query2calc = sumBookMap(query2.type, _joins);
    if (query2.direction === ENUM_BOOK_DIRECTION.NONE) {
      _o.amountA2 = query2calc.amount;
    } else if (query2.direction === ENUM_BOOK_DIRECTION.JIE) {
      _o.amountA2 = query2calc.amountJie;
    } else if (query2.direction === ENUM_BOOK_DIRECTION.DAI) {
      _o.amountA2 = query2calc.amountDai;
    }

    const query3 = getTonOrderBookQuery(type, "amountA3");
    const query3calc = sumBookMap(query3.type, _joins);
    if (query3.direction === ENUM_BOOK_DIRECTION.NONE) {
      _o.amountA3 = query3calc.amount;
    } else if (query3.direction === ENUM_BOOK_DIRECTION.JIE) {
      _o.amountA3 = query3calc.amountJie;
    } else if (query3.direction === ENUM_BOOK_DIRECTION.DAI) {
      _o.amountA3 = query3calc.amountDai;
    }

    const query4 = getTonOrderBookQuery(type, "amountA4");
    const query4calc = sumBookMap(query4.type, _joins);
    if (query4.direction === ENUM_BOOK_DIRECTION.NONE) {
      _o.amountA4 = query4calc.amount;
    } else if (query4.direction === ENUM_BOOK_DIRECTION.JIE) {
      _o.amountA4 = query4calc.amountJie;
    } else if (query4.direction === ENUM_BOOK_DIRECTION.DAI) {
      _o.amountA4 = query4calc.amountDai;
    }
    return _o;
  });
}

// ============================ 财务记录的明细账簿 ============================
// ============================ 财务记录的明细账簿 ============================
// ============================ 财务记录的明细账簿 ============================
// ============================ 财务记录的明细账簿 ============================
// ============================ 财务记录的明细账簿 ============================
// ============================ 财务记录的明细账簿 ============================

/** 创建财务记录后，要怎么对它记账 */
export function getVoucherBookType(existType: ENUM_VOUCHER) {
  if (existType === ENUM_VOUCHER.INCOME_HUOKUAN) {
    return {
      typeJIE: ENUM_BOOK_TYPE.CUN_KUAN_ZHANG_HU,
      typeDAI: ENUM_BOOK_TYPE.YING_SHOU_ZHANG_KUAN_CHECKING,
    };
  } else if (existType === ENUM_VOUCHER.INCOME_TUIKUAN) {
    return {
      typeJIE: ENUM_BOOK_TYPE.YING_SHOU_ZHANG_KUAN_RETURN_CHECKING,
      typeDAI: ENUM_BOOK_TYPE.CUN_KUAN_ZHANG_HU,
    };
  } else if (existType === ENUM_VOUCHER.INCOME_FAPIAO) {
    return {
      typeJIE: ENUM_BOOK_TYPE.ZHU_YING_YE_WU_SHOU_RU_CHECKING,
      typeDAI: ENUM_BOOK_TYPE.ZHU_YING_YE_WU_SHOU_RU_TAX,
    };
  } else if (existType === ENUM_VOUCHER.EXPENSE_HUOKUAN) {
    return {
      typeJIE: ENUM_BOOK_TYPE.YING_FU_ZHANG_KUAN_CHECKING,
      typeDAI: ENUM_BOOK_TYPE.CUN_KUAN_ZHANG_HU,
    };
  } else if (existType === ENUM_VOUCHER.EXPENSE_FAPIAO) {
    return {
      typeJIE: ENUM_BOOK_TYPE.ZHU_YING_YE_WU_CHENG_BEN_TAX,
      typeDAI: ENUM_BOOK_TYPE.ZHU_YING_YE_WU_CHENG_BEN_CHECKING,
    };
  } else {
    throw { message: "不支持此类型的财务记录" };
  }
}

/** 财务记录（货款/发票/销售/采购）在列表上要看到哪些明细账簿？*/
export function getVoucherBookQuery(voucherType: ENUM_VOUCHER, sortorKey: "amountA1" | "amountA2") {
  const { typeJIE, typeDAI } = getVoucherBookType(voucherType);
  const sortorQuery = {
    type: ENUM_BOOK_TYPE.NONE,
    direction: ENUM_BOOK_DIRECTION.NONE,
  };

  // 既和财务记录有关系，又和销售订单有关系的那个明细账簿
  if (voucherType === ENUM_VOUCHER.INCOME_HUOKUAN) {
    if (sortorKey === "amountA1") {
      sortorQuery.type = typeDAI;
      sortorQuery.direction = ENUM_BOOK_DIRECTION.NONE;
    } else if (sortorKey === "amountA2") {
      sortorQuery.type = typeDAI; // 应收帐款/待认领
      sortorQuery.direction = ENUM_BOOK_DIRECTION.JIE;
    }
  }

  // 既和财务记录有关系，又和销售订单有关系的那个明细账簿
  else if (voucherType === ENUM_VOUCHER.INCOME_TUIKUAN) {
    if (sortorKey === "amountA1") {
      sortorQuery.type = typeJIE;
      sortorQuery.direction = ENUM_BOOK_DIRECTION.NONE;
    } else if (sortorKey === "amountA2") {
      sortorQuery.type = typeJIE; // 应收帐款/待认领
      sortorQuery.direction = ENUM_BOOK_DIRECTION.DAI;
    }
  }

  // 既和财务记录有关系，又和销售订单有关系的那个明细账簿
  else if (voucherType === ENUM_VOUCHER.INCOME_FAPIAO) {
    if (sortorKey === "amountA1") {
      sortorQuery.type = typeJIE;
      sortorQuery.direction = ENUM_BOOK_DIRECTION.NONE;
    } else if (sortorKey === "amountA2") {
      sortorQuery.type = typeJIE;
      sortorQuery.direction = ENUM_BOOK_DIRECTION.DAI; // 销售发票
    }
  }

  // 既和财务记录有关系，又和采购订单有关系的那个明细账簿
  else if (voucherType === ENUM_VOUCHER.EXPENSE_HUOKUAN) {
    if (sortorKey === "amountA1") {
      sortorQuery.type = typeJIE;
      sortorQuery.direction = ENUM_BOOK_DIRECTION.NONE;
    } else if (sortorKey === "amountA2") {
      sortorQuery.type = typeJIE;
      sortorQuery.direction = ENUM_BOOK_DIRECTION.DAI; // 采购货款
    }
  }

  // 既和财务记录有关系，又和采购订单有关系的那个明细账簿
  else if (voucherType === ENUM_VOUCHER.EXPENSE_FAPIAO) {
    if (sortorKey === "amountA1") {
      sortorQuery.type = typeDAI;
      sortorQuery.direction = ENUM_BOOK_DIRECTION.NONE;
    } else if (sortorKey === "amountA2") {
      sortorQuery.type = typeDAI;
      sortorQuery.direction = ENUM_BOOK_DIRECTION.JIE; // 采购发票
    }
  }
  return sortorQuery;
}

/** 帮助财务记录，补充明细账信息 */
export function formatVoucherBook(type: ENUM_VOUCHER, vouchers: Voucher[]) {
  const list = vouchers.map((_vou: Voucher) => {
    const _o = _vou as WithBookSummary & Voucher;

    const a1Query = getVoucherBookQuery(type, "amountA1");
    const a2Query = getVoucherBookQuery(type, "amountA2");

    const sums = _vou.joinBookMapList || [];
    const a1sum = sumBookMap(a1Query.type, sums);
    if (a1Query.direction === ENUM_BOOK_DIRECTION.NONE) {
      _o.amountA1 = a1sum.amount;
    } else if (a1Query.direction === ENUM_BOOK_DIRECTION.JIE) {
      _o.amountA1 = a1sum.amountJie;
    } else if (a1Query.direction === ENUM_BOOK_DIRECTION.DAI) {
      _o.amountA1 = a1sum.amountDai;
    }

    const a2sum = sumBookMap(a2Query.type, sums);
    if (a2Query.direction === ENUM_BOOK_DIRECTION.NONE) {
      _o.amountA2 = a2sum.amount;
    } else if (a2Query.direction === ENUM_BOOK_DIRECTION.JIE) {
      _o.amountA2 = a2sum.amountJie;
    } else if (a2Query.direction === ENUM_BOOK_DIRECTION.DAI) {
      _o.amountA2 = a2sum.amountDai;
    }
    return _o;
  });
  return list;
}

/** 对财务记录和订单，进行联合记账 */
export function getVoucherTonOrderBookList(entity: Voucher, visitorId: User["uuid32"], tradables: (Tradable & { amount: number })[]) {
  const masterId = entity.refOwnerUUid32;
  const voucherType = entity.type;

  const books: Book[] = [];
  const orders = tradables.map((d) => ({ ...d, amount: toNumber(d.amount) })).filter((d) => d.amount !== 0);
  if (orders.length === 0) return books;

  const voucherBookType = getVoucherBookType(voucherType); // 财务类型有校验，有问题会报错
  const orderBookSalesType = getTonOrderBookType(ENUM_TON_ORDER.SALE);
  const orderBookSalesReturnType = getTonOrderBookType(ENUM_TON_ORDER.SALE_RETURN);
  const orderBookPurchaseType = getTonOrderBookType(ENUM_TON_ORDER.PURCHASE);

  for (const order of orders) {
    const base: Partial<Book> = {
      refOwnerUUid32: masterId,
      amount: order.amount,
      refCreatorId: visitorId,
    };
    const bookJie = { value: { ...new BookSchema(), ...base, direction: ENUM_BOOK_DIRECTION.JIE } };
    const bookDai = { value: { ...new BookSchema(), ...base, direction: ENUM_BOOK_DIRECTION.DAI } };

    // 收到货款
    if (voucherType === ENUM_VOUCHER.INCOME_HUOKUAN) {
      // 财务记录
      bookJie.value = { ...bookJie.value, ..._getBookTradable(entity) };
      bookJie.value.type = voucherBookType.typeDAI;
      // 订单
      bookDai.value = { ...bookDai.value, ..._getBookTradable(order) };
      bookDai.value.type = orderBookSalesType.typeJIE;
    }

    // 退货款
    else if (voucherType === ENUM_VOUCHER.INCOME_TUIKUAN) {
      // 订单
      bookJie.value = { ...bookJie.value, ..._getBookTradable(order) };
      bookJie.value.type = orderBookSalesReturnType.typeDAI;
      // 财务记录
      bookDai.value = { ...bookDai.value, ..._getBookTradable(entity) };
      bookDai.value.type = voucherBookType.typeJIE;
    }

    // 开出销售发票
    else if (voucherType === ENUM_VOUCHER.INCOME_FAPIAO) {
      // 订单
      bookJie.value = { ...bookJie.value, ..._getBookTradable(order) };
      bookJie.value.type = orderBookSalesType.typeDAI;
      // 财务记录
      bookDai.value = { ...bookDai.value, ..._getBookTradable(entity) };
      bookDai.value.type = voucherBookType.typeJIE;
    }

    // 付货款
    else if (voucherType === ENUM_VOUCHER.EXPENSE_HUOKUAN) {
      // 订单
      bookJie.value = { ...bookJie.value, ..._getBookTradable(order) };
      bookJie.value.type = orderBookPurchaseType.typeDAI;
      // 财务记录
      bookDai.value = { ...bookDai.value, ..._getBookTradable(entity) };
      bookDai.value.type = voucherBookType.typeJIE;
    }

    // 收到采购发票
    else if (voucherType === ENUM_VOUCHER.EXPENSE_FAPIAO) {
      // 财务记录
      bookJie.value = { ...bookJie.value, ..._getBookTradable(entity) };
      bookJie.value.type = voucherBookType.typeDAI;
      // 订单
      bookDai.value = { ...bookDai.value, ..._getBookTradable(order) };
      bookDai.value.type = orderBookPurchaseType.typeJIE;
    }

    books.push(bookJie.value);
    books.push(bookDai.value);
  }
  return books;
}

/** 获取交易七要素 */
function _getBookTradable(tradable: Tradable) {
  return {
    tradeId: tradable.tradeId,
    tradeTime: tradable.tradeTime,
    tradeYear: tradable.tradeYear,
    tradeMonth: tradable.tradeMonth,
    tradeScope: tradable.tradeScope,
    //
    refCreatorId: tradable.refCreatorId,
    refContactId: tradable.refContactId,
  };
}

/** 获取指定明细账 */
function sumBookMap(type: ENUM_BOOK_TYPE, list?: BookMap[]) {
  const match = (list || []).find((e) => e.type === type);
  return {
    amount: toNumber(match?.amount),
    amountJie: toNumber(match?.amountJie),
    amountDai: toNumber(match?.amountDai),
  };
}
